package com.actionpals.utils
{
	import com.actionpals.geom.ColorTrans;
	import com.actionpals.geom.RGB;
	import com.actionpals.geom.Tint;
	
	import flash.display.DisplayObject;
	import flash.geom.ColorTransform;
	
	/**
	 * The ColorUtil class includes a collection of utilities that allows for more intuitive color manipulation.
	 * 
	 * @author Mark Walters
	 */	
	public class ColorUtil
	{
		/**
		 * Converts a color value to a string hexadecimal value.
		 * 
		 * @param color The color value to be converted to a string hexadecimal value.
		 * @return The string hexadecimal value.
		 */
		public static function colorToString( color:uint ):String
		{
			var colorString:String = color.toString( 16 );
			var toFill:Number = 6 - colorString.length;
			while( toFill-- ) colorString = "0" + colorString;
			return colorString.toUpperCase();
		}
		
		/**
		 * Converts a string hexadecimal value to a color value.
		 * 
		 * @param colorString The string hexadecimal value to be converted to a color value.
		 * @return The color value.
		 */
		public static function stringToColor( colorString:String ):uint
		{
			colorString = colorString.substr( -6, 6 );
			var color:uint = Number( "0x" + colorString );
			return color;
		}
		
		/**
		 * Returns the color currently applied to a display object.
		 * 
		 * @param displayObject The display object of which to determine the color.
		 * @return The color currently applied to the display object.
		 */
		public static function getColor( displayObject:DisplayObject ):uint
		{
			return displayObject.transform.colorTransform.color;
		}
		
		/**
		 * Sets the color of a display object.
		 * 
		 * @param displayObject The display object of which to set the color.
		 * @param color The color to apply to the display object.
		 */		
		public static function setColor( displayObject:DisplayObject, color:uint ):void
		{
			var colorTrans:ColorTransform = new ColorTransform();
			colorTrans.color = color;
			displayObject.transform.colorTransform = colorTrans;
		}
		
		/**
		 * Returns the scaled brightness adjustment, as a decimal between -1 and 1.
		 * 
		 * @param displayObject The display object of which to determine the brightness.
		 * @return The brightness currently applied to the display object.
		 */		
		public static function getBrightness( displayObject:DisplayObject ):Number
		{
			var ct:ColorTransform = displayObject.transform.colorTransform;
			var colorTrans:ColorTrans = new ColorTrans( ct.redMultiplier, ct.greenMultiplier, ct.blueMultiplier, ct.alphaMultiplier, ct.redOffset, ct.greenOffset, ct.blueOffset, ct.alphaOffset );
			return colorTrans.brightness;
		}
		
		/**
		 * Sets the scaled brightness adjustment, as a decimal between -1 and 1.
		 * Positive values lighten the color, and a value of 1 turns the color completely white.
		 * Negative values darken the color, and a value of -1 turns the color completely black.
		 * 
		 * @param displayObject The display object of which to set the brightness.
		 * @param color The brightness to apply to the display object.
		 */		
		public static function setBrightness( displayObject:DisplayObject, brightness:Number ):void
		{
			var colorTrans:ColorTrans = new ColorTrans();
			colorTrans.brightness = brightness;
			displayObject.transform.colorTransform = colorTrans;
		}
		
		/**
		 * Returns the linear brightness adjustment, as a number between -255 and 255.
		 * 
		 * @param displayObject The display object of which to determine the brightnessOffset.
		 * @return The brightnessOffset currently applied to the display object.
		 */
		public static function getBrightnessOffset( displayObject:DisplayObject ):Number
		{
			var ct:ColorTransform = displayObject.transform.colorTransform;
			var colorTrans:ColorTrans = new ColorTrans( ct.redMultiplier, ct.greenMultiplier, ct.blueMultiplier, ct.alphaMultiplier, ct.redOffset, ct.greenOffset, ct.blueOffset, ct.alphaOffset );
			return colorTrans.brightnessOffset;
		}
		
		/**
		 * Sets the linear brightness adjustment, as a number between -255 and 255.
		 * Positive values lighten the color, and a value of 255 turns the color completely white.
		 * Negative values darken the color, and a value of -255 turns the color completely black.
		 * 
		 * @param displayObject The display object of which to set the brightnessOffset.
		 * @param color The brightnessOffset to apply to the display object.
		 */	
		public static function setBrightnessOffset( displayObject:DisplayObject, brightnessOffset:Number ):void
		{
			var colorTrans:ColorTrans = new ColorTrans();
			colorTrans.brightnessOffset = brightnessOffset;
			displayObject.transform.colorTransform = colorTrans;
		}
		
		/**
		 * Returns the percentage to invert, as a decimal value between 0 and 1.
		 * 
		 * @param displayObject The display object of which to determine the negative.
		 * @return The negative currently applied to the display object.
		 */
		public static function getNegative( displayObject:DisplayObject ):Number
		{
			var ct:ColorTransform = displayObject.transform.colorTransform;
			var colorTrans:ColorTrans = new ColorTrans( ct.redMultiplier, ct.greenMultiplier, ct.blueMultiplier, ct.alphaMultiplier, ct.redOffset, ct.greenOffset, ct.blueOffset, ct.alphaOffset );
			return colorTrans.negative;
		}
		
		/**
		 * Sets the percentage to invert, as a decimal value between 0 and 1.
		 * When negative = 0, the color is its original color and no negative color is visible.
		 * When negative = 1, the color is completely negative and none of its original color is visible.
		 * 
		 * @param displayObject The display object of which to set the negative.
		 * @param color The negative to apply to the display object.
		 */
		public static function setNegative( displayObject:DisplayObject, negative:Number ):void
		{
			var colorTrans:ColorTrans = new ColorTrans();
			colorTrans.negative = negative;
			displayObject.transform.colorTransform = colorTrans;
		}
		
		/**
		 * Returns the RGB object color value for a ColorTransform object.
		 * 
		 * @param displayObject The display object of which to determine the RGB.
		 * @return The RGB currently applied to the display object.
		 */
		public static function getRGB( displayObject:DisplayObject ):RGB
		{
			var ct:ColorTransform = displayObject.transform.colorTransform;
			var colorTrans:ColorTrans = new ColorTrans( ct.redMultiplier, ct.greenMultiplier, ct.blueMultiplier, ct.alphaMultiplier, ct.redOffset, ct.greenOffset, ct.blueOffset, ct.alphaOffset );
			return colorTrans.rgb;
		}
		
		/**
		 * Sets the RGB object color value for a ColorTransform object.
		 * 
		 * @param displayObject The display object of which to set the RGB.
		 * @param color The RGB to apply to the display object.
		 */
		public static function setRGB( displayObject:DisplayObject, rgb:RGB ):void
		{
			var colorTrans:ColorTrans = new ColorTrans();
			colorTrans.rgb = rgb;
			displayObject.transform.colorTransform = colorTrans;
		}
		
		/**
		 * Returns the tinting offset color value in the 0xRRGGBB format.
		 * 
		 * @param displayObject The display object of which to determine the tintOffset.
		 * @return The tintOffset currently applied to the display object.
		 */
		public static function getTintOffset( displayObject:DisplayObject ):uint
		{
			var ct:ColorTransform = displayObject.transform.colorTransform;
			var colorTrans:ColorTrans = new ColorTrans( ct.redMultiplier, ct.greenMultiplier, ct.blueMultiplier, ct.alphaMultiplier, ct.redOffset, ct.greenOffset, ct.blueOffset, ct.alphaOffset );
			return colorTrans.tintOffset;
		}
		
		/**
		 * Sets the tinting offset color value in the 0xRRGGBB format.
		 * 
		 * @param displayObject The display object of which to set the tintOffset.
		 * @param color The tintOffset to apply to the display object.
		 */
		public static function setTintOffset( displayObject:DisplayObject, tintOffset:uint ):void
		{
			var colorTrans:ColorTrans = new ColorTrans();
			colorTrans.tintOffset = tintOffset;
			displayObject.transform.colorTransform = colorTrans;
		}
		
		/**
		 * Retrieves the tint value; color and muliplier.
		 * Tint color is derived from the color offsets when retrieved, but accuracy decreases as the tint multiplier decreases.
		 * 
		 * @param displayObject The display object of which to determine the tint.
		 * @return The tint currently applied to the display object.
		 */		
		public static function getTint( displayObject:DisplayObject ):Tint
		{
			var ct:ColorTransform = displayObject.transform.colorTransform;
			var colorTrans:ColorTrans = new ColorTrans( ct.redMultiplier, ct.greenMultiplier, ct.blueMultiplier, ct.alphaMultiplier, ct.redOffset, ct.greenOffset, ct.blueOffset, ct.alphaOffset );
			return colorTrans.tint;
		}
		
		/**
		 * Sets the tint value; color and muliplier.
		 * When tintMultiplier = 0, the color is its original color and no tint color is visible.
		 * When tintMultiplier = 1, the color is completely tinted and none of its original color is visible.
		 * 
		 * @param displayObject The display object of which to set the tint.
		 * @param color The tint to apply to the display object.
		 */	
		public static function setTint( displayObject:DisplayObject, tint:Tint ):void
		{
			var colorTrans:ColorTrans = new ColorTrans();
			colorTrans.tint = tint;
			displayObject.transform.colorTransform = colorTrans;
		}
		
		/**
		 * Sets the tint color and amount.
		 * 
		 * @param displayObject The display object of which to set the tint values.
		 * @param color The tinting color value in the 0xRRGGBB format.
		 * @param multiplier The percentage to apply the tint color, as a decimal value between 0 and 1.
		 */		
		public static function setTintValues( displayObject:DisplayObject, color:uint, multiplier:Number ):void
		{
			var colorTrans:ColorTrans = new ColorTrans();
			colorTrans.setTint( color, multiplier );
			displayObject.transform.colorTransform = colorTrans;
		}
		
		/**
		 * Resets the color to its default values.
		 * 
		 * @param displayObject The display object of which to reset the color values.
		 */		
		public static function reset( displayObject:DisplayObject ):void
		{
			var colorTrans:ColorTrans = new ColorTrans();
			colorTrans.reset();
			displayObject.transform.colorTransform = colorTrans;
		}
		
		/**
		 * Inverts the color.
		 * 
		 * @param displayObject The display object of which to invert the color values.
		 */
		public static function invert( displayObject:DisplayObject ):void
		{
			var colorTrans:ColorTrans = new ColorTrans();
			colorTrans.invert();
			displayObject.transform.colorTransform = colorTrans;
		}
		
	}
}